perm filename PLASUB.MAC[1,LCS] blob
sn#305756 filedate 1977-09-19 generic text, type T, neo UTF8
TITLE PLAY MUSIC FILES ON THE DAC
SUBTTL DEFINITIONS
;MODIFIED FOR KI 7-APR-76 BY JIM LAWSON
ENTRY PLAY
VERNO==↑d8
; FEATURE TEST SWITCHES
ifndef ftfsub,< ftfsub==0 ; 1 for FORTRAN callable subroutine support>
IFNDEF FTMT,< FTMT==0 ; 1 FOR MAG-TAPE SUPPORT>
IFNDEF FTKSYS,< FTKSYS==0 ; 1 FOR TRPSET SUPPORT>
IFNDEF FT12B,< FT12B==1 ; 1 FOR OLD DAC (12 - BITS)>
IFNDEF FT16B,< FT16B==1 ; 1 FOR NEW DAC (16 - BITS)>
ifn ftfsub,<
ftseg==0
ftmt==0
ftksys==0 ; don't allow ksys if we're a subroutine
search formac(formac.unv[s,jrl])
EXTERNAL CEXIT.,chnget,chnrel, pshint,popint, CORGET,CORREL
.request CORFUN[DSP,JRL]
> ; end ifn ftfsub above
define mesage (arg),<
if1,<
ifn ftfsub,<printx[Assembling FORTRAN callable PLAY subroutine version arg]>
ife ftfsub,<printx[Assembling PLASUB version arg]>
>>
mesage (\verno)
SEARCH JLMAC(JLMAC.UNV[S,JRL]),UJBDAT,UUOSYM,dpyuuo,macten
EXTERNAL SBFILN
;; EXTERNAL .HELPR,SBFILN
;THE FOLLOWING ARE IN "LIB.REL[S,JRL]"
EXTERNAL PARSE,OCTSP,DECIDL,DECOUT,OCTOUT,SIXINA,TYDEV,TYSPEC
.TEXT %,/SEGMENT:LOW LIB[S,JRL]/SEARCH,SYS:HELPER%
SUBTTL DAC DEFINITIONS
DAC12=400 ; DEVICE CODE FOR OLD DAC
DAC16=404 ; DEVICE CODE FOR NEW DAC
DACPI==1 ; DAC PI CHANNEL
ON=1B31 ;SAME AS BUSY
OFF=0
DONE=1B32
BUSY=1B31
MISS=1B30
; MACRO TO REMEMBER WHERE DEVICE CODE MUST BE SET.
FTMDAC==FT12B&FT16B ; MULTIPLE DAC FLAG
DEFINE .ODFB (ADD),<POINT 3,ADD,29>
DEFINE .ODMB (ADD),<POINT 2,ADD,19>
DEFINE .ODCB (ADD),<POINT 5,ADD,26>
DEFINE .NDFB (ADD),<POINT 0,ADD,29>
DEFINE .NDMB (ADD),<POINT 0,ADD,29>
DEFINE .NDCB (ADD),<POINT 8,ADD,29>
ifon FTMDAC,<
DEFINE DACON,< PUSHJ P,@ONADD>
DEFINE DACOFF,< PUSHJ P,@OFFADD>
DEFINE DOFLT (ADD),< DPB T1,FLTPTR(P1)>
DEFINE DOCHN (ADD),< DPB T1,CHNPTR(P1)>
DEFINE DOCLK (ADD),< DPB T2,CLKPTR(P1)>
DEFINE CONCLK,< PUSHJ P,@CONADD(P1)>
> ;END IFN FTMDAC ABOVE
ifoff FTMDAC,<
DEFINE DACON,< XCT CONOWD>
DEFINE DACOFF,< CONO DAC,OFF>
ifon FT12B,< DAC = DAC12
.GDTYP==0
DEFINE DOFLT (ADD),< DPB T1,[.ODFB (ADD)]>
DEFINE DOCHN (ADD),< DPB T1,[.ODMB (ADD)]>
DEFINE DOCLK (ADD),< DPB T2,[.ODCB (ADD)]>
DEFINE CONCLK,< PUSHJ P,OCLK>
> ; END IFN FT12B ABOVE
list
ifon FT16B,< DAC = DAC16
.GDTYP==1
DEFINE DOFLT (ADD),< DPB T1,[.NDFB (ADD)]>
DEFINE DOCHN (ADD),< DPB T1,[.NDMB (ADD)]>
DEFINE DOCLK (ADD),< DPB T2,[.NDCB (ADD)]>
DEFINE CONCLK,< PUSHJ P,NCLK>
> ; END IFN FT16B ABOVE
list
> ; END IFE FTMDAC ABOVE
list
..NI==0
DEFINE REMADD (LABL),< .IO$'LABL==. >
DEFINE DACIO (IN,ADDR),<
ifon FTMDAC,<
IF1,< IFDEF ..IOP,<PRINTX \ALL DAC I/O INSTRUCTIONS MUST BE DEFINED PRIOR TO EXPANSION OF DODAC MACRO.\>>
REMADD (\..NI)
..NI==..NI+1
IN ADDR
> ; END IFN FTMDAC ABOVE
ifoff FTMDAC,<
IN DAC,ADDR
> ; END IFE FTMDAC SBOVE
list
>
ifon FTMDAC,<
DEFINE DEVPTR (LABL),<
POINT 7,.IO$'LABL,9
>
DEFINE DODAC,<
..IOP==.
..IOL==..NI
..IOA==0
REPEAT ..NI,<
DEVPTR (\..IOA)
..IOA==..IOA+1
>>
> ; END IFN FTMDAC ABOVE
list
SUBTTL CONSTANTS,ACS, AND FLAGS
NUM=↑D100 ;NUMBER OF 128 WORD BLOCKS PER BUFFER
SIZE=↑D128*NUM ;TOTAL SIZE OF EACH BUFFER
HEDLEN=200 ;SIZE OF MUSIC FILE HEADER
; EXTRA AC DEFINITIONS
T=1 ;TEMP ACC
I=2 ;ACC TO HOLD RELOCATION FACTOR
SETUP=4 ;ACC USED FOR INITIAL SETUP
DSK=5 ;INPUT CHANNEL
F=0 ;AC FOR THE FOLLOWING FLAGS.
; locking code definition
;LEFT HALF FLAGS
.UBLEW=400000 ;USING DEFAULTS BECAUSE USER BLEW IT.
ifon FTKSYS,<
.KSYS=200000 ;USER WANTS TIME-SHARING STOPPED.
> ; END IFN FTKSYS ABOVE
ifon FTMT,<
.REWMT=100000 ;USER WANTS MAG-TAPE REWOUND.
.MTDEV=040000 ;INPUT DEVICE IS MAG-TAPE.
> ;END IFN FTMT ABOVE
list
.GTSWT=010000 ;WE'VE DECODED A SWITCH
.ONLYH=004000 ;USER JUST WANTS TO SEE HEADER INFO. DON'T PLAY
.FHEAD=002000 ;FILE HAS A HEADER BLOCK.
;RIGHT HALF FLAGS
ifon FTMT,<
.ATEOF=020000 ;MAG-TAPE IS AT EOF.
.ATOBS=004000 ;AUTO BACKSPACE SWITCH.
> ; END IFN FTMT ABOVE
list
;LOCATIONS IN MUSIC FILE HEADER
IDLOC==0
CLOC==1
PLOC==2
CHNLOC==3
AMPLOC==4
TLOC==100
SUBTTL STORAGE
LOWSEG
ifoff ftfsub,<
LOC .JBVER
EXP VERNO
RELOC 0
> ; end ife ftfsub above
list
HIOWD: IOWD HEDLEN,HEADER
Z
IBP1: BLOCK 2 ;IOWD FOR INITIAL DISK TRANSFER
BP1: XWD -SIZE,0 ;IOWD FOR INPUT TRANSFERS
Z
BP2: XWD -SIZE,0 ;IOWD FOR INPUT TRANSFERS.
Z
RBP1: BLOCK 2 ;RELOCATED IOWD FOR BF1.
RBP2: BLOCK 2 ;RELOCATED IOWD FOR BF2.
SLPTIM: 0 ;TIME TO SLEEP WAITING FOR DAC.
TIOWD: 0 ;VALUE OF dac IOWD WHEN WE CAN START REFILL.
LIOWD: 0 ;LAST IOWD
diowd: 0 ;IOWD FOR BLKO
OLDSIZ: BLOCK 1 ; SIZE BEFORE CORING UP FOR BUFFERS
PDL: BLOCK 20
SSTINS: SETSTS DSK,.IODPR ; SET STATUS IN CASE OR ERRORS.
OSPEC: UU.DEL!UU.DER!400!.IODPR ; DISABLE ERROR LOGGING AND ERROR RETRY.
DEV: SIXBIT /DSKM/
0
ifon FTMT,<
MTPOS: 0 ;MAG-TAPE POSITION COUNTER.
MTSPEC: 0 ;BLOCK FOR MTCHR. UUO
BLOCK 12
MTNFB: 0 ;NO. OF FILES FROM BOT.
> ; END IFN FTMT ABOVE
list
FILE: SIXBIT /MUSIC/
EXT: SIXBIT /MSB/
;EXTENDED LOOKUP BLOCK TO GET FILE LENGTH
EXLKUP: EXP NARGS
FILPPN: 0
FILNAM: SIXBIT /MUSIC/ ;FILNAM GETS INFO FROM FILE ANYWAY!
FILEXT: SIXBIT /MSB/
FILPRV: EXP 0
FILSIZ: 0
NARGS==.-1-EXLKUP
MUSPPN: 0 ;DEFAULT PPN
MYPPN: 0 ;USER'S PPN
INDEX: 0 ;SAVE RELOCATION FACTOR
MFLG: 0 ;FLAG FOR DATA MISSED
DFLG: 0 ;FLAG FOR DONE
ifon FTKSYS,<
KILFLG: 0 ;TIME-SHARING IS STOPPED FLAG.
> ; END IFN FTKSYS ABOVE
list
TPOINT: 0 ;NEXT IOWD FOR INTERRUPT ROUTINE
WHATBF: 0 ;BUFFER POINTER -1=BUFFER 1, +1=BUFFER 2.
RUNHPQ: 0 ;HIGHEST HIGH PRIORITY QUEUE AVAILABLE.
DSKHPQ: XWD DSK,0 ;HIGHEST DISK HIGH PRIORITY QUEUE.
INBF: 0 ;START OF CHANNEL COMMAND LIST FOR INPUT.
Z ;TERMINATES CHANNEL COMMAND LIST
; VARIABLES USED BY THE DACS.
DACSTT: 0 ; DAC STATUS AS READ BY CONI
;POINTER TO DAC PARAMETERS TO BE USED FOR CURRENT CONVERSION.
ifon FTMDAC,<
NSAMPW: 0 ; NUMBER OF SAMPLES PER WORD IN FILE.
TYPE: FTYPE ; POINTER TO LOCATION CONTAINING FILE TYPE
> ; END IFN FTMDAC ABOVE
list
NCHNS: FNCHNS ; POINTER TO LOCATION CONTAINING NUMBER OF CHANNELS
SRATE: FSRATE ; POINTER TO WORD CONTAINING SAMPLING RATE
FILTR: FFILTR ; POINTER TO WORD CONTAINING DEFAULT FILTER SETTINGS
;DAC PARAMETERS AS READ FROM FILE HEADER
ifon FTMDAC,<
FTYPE: 0
> ; END IFN FTMDAC ABOVE
list
FNCHNS: 1
FSRATE: ↑D10000
FFILTR: 2
ifon ftfsub,<
spcadd: point 7,0 ; byte pointer to file name for FORTRAN call.
chncor: 5,,0 ; place to save channel,,core we got from FOROTS
> ; end ifn ftfsub
list
;DAC PARAMETERS AS SPECIFIED BY USER
ifon FTMDAC,<
TTYPE: 0
> ; END IFN FTMDAC ABOVE
list
TNCHNS: 1
TSRATE: ↑D10000
TFILTR: 2
ifon FTMDAC,<
; POINTERS TO BYTES IN THE CONOWD. INDEXED BY DAC TYPE
FLTPTR: .ODFB (CONOWD) ; FILTER SETTING BITS
.NDFB (CONOWD)
CHNPTR: .ODMB (CONOWD) ; NO. OF CHANELS BITS
.NDMB (CONOWD)
CLKPTR: .ODCB (CONOWD) ; CLOCK RATE BITS
.NDCB (CONOWD)
; POINTERS TO SUBROUTINES TO TURN DAC ON AND OFF
ONADD: ODACON
OFFADD: ODACOF
> ; END IFN FTMDAC ABOVE
list
SUBTTL INTERRUPT PROCESSING
ifon FTKSYS,<
;PLACE TO SAVE LOCATIONS 42 AND 43 IF WE TRPSET
PIWRD1: 0 ;CONTENTS OF LOCATION 42
PIWRD2: 0 ;CONTENTS OF LOCATION 43
;WORDS TO STICK ON PI LOCATIONS IF WE TRPSET.
BLKOW: DACIO (BLKO,diowd)
TRPADR: JSR INTRPT
> ; END IFN FTKSYS ABOVE
list
;START OF INTERRUPT ROUTINE
INTRPT: 0 ;INTERRUPT ROUTINE
EXCHWD: EXCH I,INDEX ;GET RELOCATION FACTOR AND SAVE I
EXCH T,TPOINT(I) ;SAVE T AND GET NEXT IOWD
DACIO (CONSZ,MISS) ;CHECK FOR DATA MISSED
SETOM MFLG(I) ;YES RAISE MISSED FLAG
MOVNS WHATBF(I) ;POINT WHATBF TO NEXT BUFFER
JUMPGE T,IDACOF(I) ;IF 0 NO IOWD READY. TURN OFF DAC.
MOVEM T,diowd(I) ;RESTORE BLKO POINTER
RETURN: SETZ T, ;ZERO IOWD
EXCH T,TPOINT(I) ;RESTORE T AND IOWD
EXCH I,INDEX(I) ;RESTORE I AND INDEX
JENWD: JRSTF @INTRPT ;DISMISS INTERRUPT
IDACOF: DACIO (CONO,OFF) ;TURN OFF DAC
SETOM DFLG(I) ;RAISE DONE FLAG
ifon FTKSYS,<
AOSE KILFLG(I) ;DID WE TRPSET?
JRST RETURN(I) ;RESTORE AND DISMISS
CONO PI,1B22!1B29 ;IN CASE OF PANIC STOP
MOVE T,PIWRD1(I) ;RESET LOCATION 42
MOVEM T,42
MOVE T,PIWRD2(I) ;RESET LOCATION 43
MOVEM T,43
> ; END IFN FTKSYS ABOVE
list
JRST RETURN(I) ;AND RETURN
CONOWD:
ifon FTMDAC,<
DACIO (CONO,DACPI) ;START DAC ON CHANNEL 1
> ; END IFN FTMDAC
ifoff FTMDAC,<
IFN FT12B,< DACIO (CONO,ON!DACPI)>
IFN FT16B,< DACIO (CONO,DONE!ON!DACPI)>
> ; END IFE FTMDAC
list
CCINT: -1 ;KLUDGE FOR LOSING SYSTEM.
INTBLK: 4,INTLOC ;↑C BLOCK
2
0
0
RTBLK: XWD 1,INTRPT ;PI CH 1,SUBROUTINE ADDRESS
XWD 1,HEAVEN ;CAN'T GET THERE.
DACIO (BLKO,diowd)
0
RTBOFF: BLOCK 4
HEAVEN: 0
HALT
HEADER: BLOCK HEDLEN
subttl high seg constants
HGHSEG
CRLF: BYTE (7)15,12,0
ifon FTMDAC,<
; POINTERS TO DAC SPECIFIC ROUTINES ( INDEXED BY DAC TYPE 0=12BIT,1=16BIT)
DACDEV: XWD 3,DAC12 ; # OF SAMPLES PER WORD,DEVICE CODE.
XWD 2,DAC16
CONADD: OCLK
NCLK
; POINTERS TO ROUTINES TO START AND STOP THE DAC. INDEXED BY DAC TYPE
DACADD: ODACON,,ODACOF
NDACON,,NDACOF
> ; END IFN FTMDAC ABOVE
list
SUBTTL PROGRAM INITIALISATION - start,
;HERE ON PROGRAM START-UP
ifoff ftfsub,<
PLAY:
MOVE 0,SBFILN ;OUTPUT NAME FROM 'MUSIC' (6-BIT)
MOVEM 0,FILE
;;;PLAY: RESET
> ; end ife ftfsub above
ifon ftfsub,<
entryp (play,<plyfil>)
hrrzi t1,@plyfil(l) ; get address of array containing file name
hrli t1,(point 7,0) ; make byte pointer
movem t1,spcadd ; save it for inchad.
> ; end ifn ftfsub
list
GETPPN T1, ;GET USER'S PPN
JFCL
MOVEM T1,MYPPN ;SAVE IT.
PJOB T1, ;GET MY JOB #.
HRLZS T1 ;SET UP FOR GETTAB.
HRRI T1,.GTPRV ;GET SOME JOB DATA.
GETTAB T1,
SETZ T1, ;LOSING.
; LDB T2,[POINT 4,T1,9];LIKE... MAX. HPQ
ldb t2,[pointr (t1,jp.hpq)] ; pointer to max run hpq for this job.
MOVEM T2,RUNHPQ ;SAVE IT.
; LDB T2,[POINT 3,T1,2];AND DISK HPQ.
ldb t2,[pointr (t1,jp.dpr)] ; pointer to max disk hpq for this job.
HRRM T2,DSKHPQ
txnn t1,jp.lck ; can we lock?
jrst [outstr [asciz/
?Sorry, you don't have LOCKING privileges. Can't run./]
exit]
txnn t1,jp.rtt ; can we rttrp?
jrst [outstr [asciz/
?Sorry, you do not have RTTRP privileges. Can't run./]
exit]
ifoff ftfsub,<
;;; OUTSTR [ASCIZ \TYPE /H FOR HELP
;;;\]
ifon FTMT,<
MOVEI F,.ATOBS!.ATEOF ;DEFAULT IS AUTO BACKSPACE ON.
> ; END IFN FTMT ABOVE.
; FALL THROUGH TO COMMAND LOOP
SUBTTL COMMAND LOOP
; FALL THROUGH FROM ABOVE (still in ftfsub conditional)
RETRY2: JFCL ;**** PDL IN MAIN PROG.
;;;RETRY2: MOVE P,[IOWD 20,PDL] ;SET-UP PDL
ifon FTKSYS,<
SETZM KILFLG ;CLEAR SYSTEM IS DEAD FLAG.
> ; END IFN FTKSYS
list
HRRZS F ;CLEAR TEMP PART OF F.
ifon FTMT,<
SETZM MTPOS ;ZERO MAG-TAPE POSITION COUNTER.
> ; END IFN FTMT
list
OUTSTR [ASCIZ/
PLAY=<RETURN> EXIT=X /] ;PROMPT USER
MOVE P1,DEV ;SET UP DEFAULTS
> ; end ife ftfsub on previous page
list
ifn ftfsub,< move p1,[sixbit/dskm/] >
MOVE P2,FILE
MOVE P3,EXT
SKIPN P4,MUSPPN
MOVE P4,MYPPN ;USE MINE IF NO MUS
MOVEI P5,INCHAD ;AND ADDRESS OF ROUTINE TO GET CHARACTER
PUSHJ P,PARSE ;GET A FILE SPEC
JRST SYNERR ;CAN'T UNDERSTAND
CAME P2,[SIXBIT/X/]
JRST XPLAY
OUTSTR [ASCIZ/ PLEASE DELETE SOUND FILES WHEN DONE./]
POPJ P, ;GOES HOME
XPLAY: MOVEM P1,DEV ;SET-UP DEVICE FOR OPEN
MOVEM P2,FILNAM ;SET UP IN ENTER BLOCK
MOVEM P3,FILEXT ;SET UP EXTENSION.
MOVEM P4,FILPPN
ifoff ftfsub,<
MOVEM P2,FILE ;YUP. AND REMEMBER IT.
MOVEM P3,EXT
MOVEM P4,MUSPPN
JUMPL T4,SWTCHK ;DON'T RE-INITIALISE DAC PARAMETERS IF NO FILE
MOVEI T2,FNCHNS ;SET PARAMETER POINTER TO FILE INFO
MOVEM T2,NCHNS
MOVEI T2,FSRATE
MOVEM T2,SRATE
ifon FTMDAC,<
MOVEI T2,FTYPE
MOVEM T2,TYPE
> ; END IFN FTMDAC ABOVE
list
MOVEI T2,FFILTR
MOVEM T2,FILTR
; FALL THROUGH TO SWITCH SCANNING
SUBTTL SWITCH SCANNING
;FALL THROUGH FROM ABOVE (still in ftfsub conditional)
SWTCHK: CAIE T1,"/" ;SWITCH DELIMITER?
JRST NOSWIT ;NOPE. DON'T RESET CONOWD
PUSHJ P,SIXINA ;GET ALPHA-BETIC SIXBIT
JUMPE P1,SYNERR ;DON'T ACCEPT BLANK SWITCHES.
SUBI P2,6 ;NO OF CHARACTERS WE DIDN'T GET.
IMULI P2,6 ;NO OF PLACES TO SHIFT.
LSH P1,(P2) ;SHIFT SWITCH.
MOVSI P3,-COMSL ;SET UP AOBJN POINTER
TLZ F,.GTSWT ;CLEAR GOT SWITCH BIT.
SCNXT: MOVE T2,COMSN(P3) ;GET SWITCH
LSH T2,(P2) ;POSITION IT FOR COMPARISON.
CAMN T2,P1 ;MATCH?
JRST GMATCH ;YUP.
CONSCN: AOBJN P3,SCNXT ;NOPE. ANY MORE?
TLNN F,.GTSWT ;DID WE GET A MATCH?
JRST SYNERR ;NOPE. COMPLAIN.
GOTIT: POPJ P, ;PROCESS IT.
GMATCH: TLOE F,.GTSWT ;HAVE WE ALREADY FOUND THIS SWITCH?
JRST AMBIG ;COMPLAIN.
MOVE T2,COMSD(P3) ;GET ITS DISPATCH ENTRY,
PUSH P,T2 ;SAVE IT
TLNE T2,SW.OK1 ;NEED WE GO FURTHER?
JRST GOTIT ;NOPE.
JRST CONSCN ;AND CONTINUE SCAN.
AMBIG: POP P,P3 ;FIX THE STACK
OUTSTR [ASCIZ /
?AMBIGUOUS SWITCH
/]
TLO F,.UBLEW ;SET USER BLEW IT FLAG
JRST SWTCHK ;AND CONTINUE SCAN.
NOSWIT: CAIE T1,12 ;GOT LINE-FEED?
CAIN T1,33 ;OR ESCAPE?
JRST GOTEOL
CAIE T1," " ;WELL THEN, WAS IT A SPACE ?
CAIN T1,"," ;OR COMMA?
JRST EATCHR ;YUP. EAT IT UP.
CAIE T1,15 ;IT BETTER BE A <CR>
JRST SYNERR ;NOPE. COMPLAIN.
EATCHR: PUSHJ P,(P5) ;NOPE. EAT ANOTHER CHARACTER
JRST SWTCHK ;TRY AGAIN
; still in ftfsub conditional
SUBTTL SWITCHES
; still in ftfsub conditional
;DISPATCH TABLE BITS
SW.OK1=100 ;ACCEPT SINGLE LETTER FOR THIS SWITCH
DEFINE SCAN(PFX),<
DEFINE X($NAME,$BITS,$DSPAT),<
EXP SIXBIT /$NAME/
>
PFX'N: SWTCHS
PFX'L==.-PFX'N
DEFINE X($NAME,$BITS,$DSPAT),<
XWD $BITS,$DSPAT
>
PFX'D: SWTCHS
>
DEFINE SWTCHS,<
X (MODE,SW.OK1,SMODE)
X (CLOCK,SW.OK1,SCLOCK)
X (FILTER,SW.OK1,SFILT)
ifon FTKSYS,<
X (KSYS,SW.OK1,SKILL)
> ; END IFN FTKSYS ABOVE
ifon FTMT,<
X (REWIND,SW.OK1,SREWMT)
X (ADVANC,,SFORMT)
X (BACKSP,SW.OK1,SBAKMT)
X (NOAUTO,SW.OK1,SNAUTO)
X (AUTOBS,,SAUTO)
> ; END IFN FTMT ABOVE
list
; x (aid,sw.ok1,getaid)
;; X (HELP,SW.OK1,GETHLP)
X (WHAT,SW.OK1,STELL)
ifon FTMDAC,<
X (TYPE,SW.OK1,STYPE)
> ; END IFN FTMDAC ABOVE
list
>
SCAN COMS
; still in ftfsub conditional
SUBTTL SWITCH PROCESSING
; still in ftfsub conditional
ifon FTMDAC,<
; HERE TO SET WHICH DAC - /TYPE: SWITCH
STYPE: PUSHJ P,DECIDL ; GET DAC SPECIFICATION
CAIN P1,↑D12 ; 12 - BIT DAC ?
JRST SODAC ; YUP. GO SET UP FOR OLD ONE
CAIN P1,↑D16 ; 16 - BIT DAC ?
JRST SNDAC
OUTSTR [ASCIZ/
? ONLY 12 OR 16 BIT DACS SUPPORTED
/]
TLO F,.UBLEW ; SET "USER BLEW IT" FLAG.
JRST SWTCHK ; AND CHECK FOR MORE SWITCHES
SODAC: SKIPA T2,[EXP 0] ; GET OLD DAC DEVICE CODE
SNDAC: MOVEI T2,1 ; GET NEW DAC DEVICE CODE
MOVEM T2,TTYPE ; SAVE DEVICE CODE
MOVEI T2,TTYPE
MOVEM T2,TYPE
JRST SWTCHK ; LOOP FOR MORE SWITCHES
> ; END IFN FTMDAC ABOVE
list
;HERE TO SET MODE - /M SWITCH
SMODE: PUSHJ P,DECIDL ;GET NUMBER OF CHANNELS
JUMPE P1,SWTCHK ;MODE 0 IS A LOSER.
CAIG P1,4 ;ONLY 4 CHANNELS
JRST GOTMOD ;OK
OUTSTR [ASCIZ /
MAXIMUM OF 4 CHANNELS
/]
TLO F,.UBLEW ;SET "USER BLEW IT" FLAG.
JRST .+2
GOTMOD: CAIN P1,3 ;3 REALLY MEANS 4.
MOVEI P1,4
MOVEM P1,TNCHNS ;SAVE NUMBER OF CHANNELS
MOVEI P1,TNCHNS
MOVEM P1,NCHNS ;RESET PARAMETER POINTER
JRST SWTCHK ;AND CHECK FOR MORE SWITCHES
; still in ftfsub condtional
;HERE TO SET CLOCK - /C SWITCH
; still in ftfsub conditional
SCLOCK: PUSHJ P,DECIDL ;GET A NUMBER.
JUMPE P1,SWTCHK ;0 IS A LOSING CLOCK RATE.
PUSH P,T1 ;SAVE DELIMITER.
CAIGE P1,↑D4000 ;DOES HE MEAN KC ?
IMULI P1,↑D1000 ;ASSUME SO.
SKIPE T2,P2 ;GET EXPONENT
IDIVI P1,↑D10 ;DO THE DIVIDE.
SOJG T2,.-1 ;LOOP.
MOVEM P1,TSRATE ; SAVE SAMPLING RATE.
MOVEI T1,TSRATE
MOVEM T1,SRATE
POP P,T1 ;RESTORE DELIMITER
JRST SWTCHK ;CHECK FOR MORE SWITCHES
;HERE TO SET FILTERS
SFILT: PUSHJ P,DECIDL ;GET FILTER SETTING
JUMPN P2,BADFLT ;FRACTIONAL FILTERS ARE OUT.
CAIG P1,2
JRST GOTFLT
BADFLT: OUTSTR [ASCIZ /
POSSIBLE FILTER SETTINGS ARE 0,1, OR 2.
/]
MOVEI P1,2
TLO F,.UBLEW ;SET USER BLEW IT FLAG.
GOTFLT: MOVEM P1,TFILTR ;SAVE FILTER SETTINGS
movei t2,tfiltr
movem t2,filtr ; point filter to the right place
JRST SWTCHK
; still in ftfsub conditional
;HERE TO SET "KILL SYSTEM" FLAG -/K SWITCH
; still in ftfsub conditional
ifon FTKSYS,<
SKILL: TLO F,.KSYS ;REMEMBER...
JRST SWTCHK
> ; END IFN FTKSYS ABOVE
list
; HERE ON "WHAT" SWITCH - /W SWITCH
STELL: PUSH P,T1 ;SAVE DELIMITER
TLO F,.ONLYH ;DON'T PLAY.
ifon FTMDAC,<
OUTSTR [ASCIZ /CURRENT DAC = /]
HRRZ T1,@TYPE ; GET TYPE
OUTSTR @[EXP [ASCIZ /12 - BIT/]
EXP [ASCIZ /16 - BIT/]](T1)
> ; END IFN FTMDAC ABOVE
list
OUTSTR [ASCIZ /
CURRENT SAMPLING RATE = /]
HRRZ T1,@SRATE
PUSHJ P,DECOUT
OUTSTR [ASCIZ /
CURRENT FILTER SETTINGS = /]
MOVE T1,@FILTR
PUSHJ P,DECOUT
OUTSTR [ASCIZ /
CURRENT # OF CHANNELS = /]
MOVE T1,@NCHNS
PUSHJ P,DECOUT
OUTSTR [ASCIZ /
/]
POP P,T1
JRST SWTCHK
;HERE TO TYPE OUT HELP MESSAGE - /H SWITCH
;;GETHLP: PUSH P,T1 ;SAVE DELIMITER
;; TLO F,.ONLYH ;FORGET ABOUT PLAYING
;; MOVE T1,[SIXBIT /PLAY/]
;; PUSHJ P,.HELPR ;CALL HELP
;; TLO F,.UBLEW ;PICK UP MORE SWITCHES,
;; POP P,T1 ;RESTORE DELIMITER
;; JRST SWTCHK ;BUT DON'T PLAY.
; still in ftfsub conditional
SUBTTL MAG TAPE SWITCHES
; still in ftfsub conditional
ifon FTMT,<
;HERE TO REWIND MAG TAPE - /W SWITCH
SREWMT: TLO F,.REWMT ;SET REWIND FLAG.
JRST SWTCHK
;HERE TO ADVANCE FILES ON MAG-TAPE -/A SWITCH
SFORMT: PUSHJ P,DECIDL ;GET ADVANCE COUNT
SKIPN P1
AOJ P1, ;0=1
JUMPN P2,BADMT ;FRACTIONAL ADVANCES ARE DUBIOUS.
UPDPOS: ADDM P1,MTPOS ;UPDATE POSITION COUNTER
JRST SWTCHK ;AND CHECK FOR MORE SWITCHES.
;HERE TO BACKUP FILES ON MAG-TAPE - /B SWITCH
SBAKMT: PUSHJ P,DECIDL ;GET BACKUP COUNT
SKIPN P1
AOJ P1,
JUMPN P2,BADMT
MOVNS P1
JRST UPDPOS ;UPDATE POSITION COUNTER.
BADMT: TLO F,.UBLEW ;SET THE USER BLEW IT FLAG
OUTSTR [ASCIZ /
?FRACTIONAL MAG-TAPE POSITIONING IS DUBIOUS.
/]
JRST SWTCHK ;AND CHECK FOR MORE SWITCHES.
;HERE TO SET AUTO BACKSPACE MODE.
SAUTO: TRO F,.ATOBS
JRST SWTCHK
;HERE TO CLEAR AUTO BACKSPACE MODE.
SNAUTO: TRZ F,.ATOBS
JRST SWTCHK
> ; END FTMT CONDITIONAL ABOVE
list
; still ftfsub condtional
subttl lookup file and read in header
; still in ftfsub conditional
GOTEOL: TLNE F,.UBLEW ;FORGET ABOUT PLAYING IF USER
JRST RETRY2 ;BLEW IT.
> ; end ife ftfsub conditional from many pages ago
ifon ftfsub,<
movei t3,dsk ; get the number of the i/o channel we want
pushj p,chnget ; get the i/o channel
jrst [outstr [asciz\
?couldn't get i/o channel 5 from FOROTS.
Tell Jim to make this program smarter.\]
exit]
> ; end ifn ftfsub above
list
OPEN DSK,OSPEC
JRST INITER
ifon FTMT,<
MOVEI T1,DSK ;NOW WHAT KIND OF DEVICE IS THAT?
DEVCHR T1,
TLO F,.MTDEV ;PRETEND IT'S MAG-TAPE
TLNN T1,(DV.DIR) ;DOES IT HAVE A DIRECTORY?
JRST NOLKUP ;NOPE. DON'T BOTHER WITH LOOKUP.
LKUP: TLZ F,.MTDEV ;CLEAR MAG-TAPE BIT.
> ; END IFN FTMT ABOVE
list
LOOKUP DSK,EXLKUP ;DO EXTENDED LOOK-UP TO GET FILE LENGTH
JRST LKUPER
showit dsk, ; show progress
jfcl
NOLKUP: TLZ F,.FHEAD ;CLEAR HEADER BIT.
IN DSK,HIOWD ;READ IN THE HEADER
JRST .+2
JRST HEDERR ;WHAT CAN THIS MEAN?
MOVE T1,IDLOC+HEADER ;GET UNLIKELY WORD
CAME T1,[525252525252]
JRST NOHEAD ;DOESN'T HAVE ONE.
HRRZ T1,PLOC+HEADER ; CHECK PACKING MODE.
ifoff FTMDAC,<
CAIN T1,.GDTYP ; ALLOWABLE MODE ?
> ; END IFE FTMDAC ABOVE
ifon FTMDAC,<
JUMPE T1,GPAK ; ITS 12-BIT. GO AHEAD.
CAIN T1,1 ; 16 - BIT. THAT'S OK TOO.
> ; END IFN FTMDAC ABOVE
list
JRST GPAK
OUTSTR [ASCIZ/
?FILE IS NOT IN PROPER MODE FOR PLAYING.
/]
JRST RETRY2
GPAK:
ifon FTMDAC,<
MOVEM T1,FTYPE ; SAVE FILE TYPE
> ; END IFN FTMDAC ABOVE
list
MOVE T1,CHNLOC+HEADER;SET UP DEFAULTS
MOVEM T1,FNCHNS ;SAVE NUMBER OF CHANNELS
HRRZ P1,CLOC+HEADER
MOVEM P1,FSRATE
TLO F,.FHEAD ;REMEMBER FILE HAS A HEADER
ifon ftfsub,<
jrst nopos ; go and play
nohead: outstr [asciz/
?File doesn't have a header!
/]
retry2: popj p,
> ; end ifn ftfsub above
ifoff ftfsub,<
;CHECK FOR /WHAT SWITCH
NOHEAD: TLNN F,.ONLYH ; JUST WANT TO READ HEADER ?
JRST NOWHAT ; NOPE. GO ON AND PLAY
; FALL THROUGH TO HEADER TYPE OUT
; still in ftfsub conditional
SUBTTL HEADER TYPE OUT
; still in ftfsub conditionl
;HERE AFTER WE'VE LOOKED UP THE FILE AND READ IN THE HEADER BLOCK
TELL: OUTSTR [ASCIZ /FILE NAME - /]
MOVE T1,DEV
MOVE T2,FILE
MOVE T3,EXT
MOVE T4,MUSPPN
PUSHJ P,TYSPEC ;TYPE THE FILE SPEC.
TLNN F,.FHEAD ;DOES FILE HAVE A HEADER?
JRST NOHEDR ;NOPE. FORGET ABOUT IT.
ifon FTMDAC,<
OUTSTR [ASCIZ/
FILE TYPE IS /]
HRRZ T1,FTYPE ; GET TYPE ACCORDING TO FILE
OUTSTR @[EXP [ASCIZ/12 - BIT/]
EXP [ASCIZ/16 - BIT/]](T1)
> ; END IFN FTMDAC ABOVE
list
OUTSTR [ASCIZ /
SAMPLING RATE = /]
HRRZ T1,FSRATE ;GET SAMPLING RATE
PUSHJ P,DECOUT ;TYPE RATE
OUTSTR [ASCIZ /
NUMBER OF CHANNELS = /]
MOVE T1,FNCHNS ;GET NUMBER OF CHANNELS
PUSHJ P,DECOUT
OUTSTR [ASCIZ /
/]
SKIPE TLOC+HEADER ;ANY TEXT?
OUTSTR TLOC+HEADER
JRST .+2
NOHEDR: OUTSTR [ASCIZ /
[FILE DOESN'T HAVE A HEADER]/]
OUTSTR [ASCIZ /
/]
; MOVNI T1,1
; TLNE F,.MTDEV ;IS IT MAG-TAPE?
; PUSHJ P,BAKWRD ;YUP. BACKSPACE OVER HEADER BLOCK
JRST RETRY2
; still in ftfsub conditional
SUBTTL MAG TAPE PRE-POSITIONING
; still in ftfsub conditional
NOWHAT:
ifon FTMT,<
;START POSITIONING IF MAG-TAPE.
TLNN F,.MTDEV ;IS INPUT DEVICE MAG-TAPE?
JRST NOPOS ;NOPE. FORGET POSITIONING
;HERE TO POSITION MAG-TAPE BEFORE PLAYING.
TLNE F,.REWMT ;DO A REWIND?
MTREW. DSK, ;YUP.
SKIPN T1,MTPOS ;POSITION THE TAPE?
JRST DONPOS ;NOPE. CONTINUE.
JUMPG T1,FORWRD ;YUP. SPACE FORWARD.
PUSHJ P,BAKWRD ;DO THE BACKSPACE.
JRST DONPOS
FORWRD: MTSKF. DSK, ;SPACE FORWARD
MTWAT. DSK, ;WAIT FOR IT.
STATZ DSK,IO.EOT ;HIT END OF TAPE?
JRST EOTER ;YUP. TELL USER.
SOJG T1,FORWRD ;LOOP
DONPOS: MTWAT. DSK, ;WAIT FOR POSITIONING TO FINISH.
SETZM MTPOS ;CLEAR POSITION COUNTER.
> ; END FTMT CONDITIONAL ABOVE
list
; FALL THROUGH TO DAC CONTROL WORD SETUP.
SUBTTL SET UP DAC CONTROL WORD
> ; end ife ftfsub conditional from many pages ago
list
; FALL THROUGH FROM ABOVE
NOPOS:
ifon FTMDAC,<
MOVE P1,@TYPE ; GET POINTER TO APPROPRIATE DAC SPECS.
MOVE T1,DACADD(P1) ; GET ON,,OFF ADDRESSES
HLRZM T1,ONADD ; SET ON ADDRESS
HRRZM T1,OFFADD ; SET OFFADD
HRRZ T1,DACDEV(P1) ; GET DAC DEVICE CODE.
ASH T1,-2
MOVSI T3,-..IOL ; SET UP AOBJN WORD FOR POINTER LIST
DEVLOP: MOVE T2,..IOP(T3) ; GET POINTER WORD
DPB T1,T2 ; STICK DAC DEVICE CODE IN WORD
AOBJN T3,DEVLOP ; LOOP
HLRZ T1,DACDEV(P1) ; GET SAMPLES PER WORD
MOVEM T1,NSAMPW ; SAVE IT FOR TIMING CALCULATIONS
> ; END IFN FTMDAC ABOVE
list
MOVE T1,@FILTR ;GET FILTER SETTINGS
DOFLT (CONOWD)
MOVE T1,@NCHNS ;GET NUMBER OF CHANNELS
cain t1,4 ; 4 channels ?
movei t1,3 ; means 3.
DOCHN (CONOWD)
CONCLK
JRST [MOVEM T1,TSRATE
OUTSTR [ASCIZ/[USING CLOCK RATE OF /]
PUSHJ P,DECOUT
OUTSTR [ASCIZ/]
/]
MOVEI T1,TSRATE
MOVEM T1,SRATE
JRST .+1]
DOCLK (CONOWD)
; FALL THROUGH TO SET VARIOUS IOWD'S.
SUBTTL SET UP VARIOUS IOWD'S.
; FALL THROUGH FROM ABOVE
SIOWD: SETZM LIOWD ;CLEAR LAST IOWD.
MOVN T1,FILSIZ ;GET NEGATIVE LENGTH OF FILE IN WORDS
ADDI T1,HEDLEN ;PLUS WHAT WE'VE READ SO FAR.
JUMPGE T1,NULFIL ;DON'T BOTHER PLAYING NULL FILES.
IDIVI T1,SIZE ;WHAT WE REALLY WANT IS THE REMAINDER
SKIPN T2 ; EXACTLY ONE BUFFER?
MOVNI T2,SIZE ; YES. LAST IOWD IS A FULL BUFFER
HRLZM T2,LIOWD ;SAVE AS LAST IOWD
MOVEI T1,SIZE ;GET BUFFER SIZE
IMULI T1,↑D15 ; * TRANSFER RATE PER WORD (IN MICRO SECS.)
IMUL T1,@NCHNS ; * NUMBER OF CHANNELS
HRRZ T3,@SRATE ; GET SAMPLING RATE
MUL T1,T3 ; * SAMPLING RATE
DIV T1,[↑D1000000] ; / 10↑-6
ifon FTMDAC,<
IDIV T1,NSAMPW ; / NO. OF SAMPLES PER WORD.
> ; END IFN FTMDAC ABOVE
ifoff FTMDAC,<
ifon FT12B,<
IDIVI T1,3 ; / NO OF SAMPLES PER WORD
> ; END IFN FT12B ABOVE
ifon FT16B,<
IDIVI T1,2 ; / NO OF SAMPLES PER WORD
> ; END IFN FT16B ABOVE
> ; END IFE FTMDAC ABOVE
list
MOVNS T1 ;NEGATE IT.
HRLZM T1,TIOWD ;SET COUNT FOR TIMING IOWD
ADDI T1,SIZE
HRRM T1,TIOWD ;SET ADDRESS FOR TIMING IOWD.
xlist
IFN 0,< ;THIS DOESN'T WORK ON LOSING SYSTEMS.
IFN FTMDAC,<
IMUL T1,NSAMPW ;NOW COMPUTE TIME .
> ; END IFN FTMDAC ABOVE
IFE FTMDAC,<
IFN FT12B,<
IMUL T1,3 ; COMPUTE TIME
> ; END IFN FT12B ABOVE
IFN FT16B,<
IMUL T1,2
> ; END IFN FT16B ABOVE
> ; END IFE FTMDAC ABOVE
MULI T1,↑D1000 ;IN MILLISECONDS.
HRRZ T3,@SRATE ; GET SAMPLING RATE
DIV T1,T3
IDIV T1,@NCHNS
SUBI T1,UUOLOS ;FUDGE FOR LOSING SYSTEM.
MOVEM T1,SLPTIM
> ;END IFN 0,
list
ifoff ftfsub,<
HRRZ T1,.JBFF ;HOW BIG ARE WE?
MOVEM T1,OLDSIZ ; SAVE OUR PREVIOUS SIZE
SOJ T1, ;FUDGE IT FOR THE IOWD
HRRM T1,BP1 ;SAVE AS IOWD ADDRESS
ADDI T1,SIZE ;SIZE OF A BUFFER
HRRM T1,BP2 ;BUFFER 2 IOWD.
ADDI T1,SIZE+1 ;REQUEST 2 BUFFERS WORTH.
CORE T1, ;NOPE. GET SOME MORE CORE.
JRST CORER ;YOU LOSE.
> ;end ife ftfsub above
ifon ftfsub,<
movei t3,2*size ; get 2 buffers worth of core
PUSHJ P,CORGET ;GET THAT MUCH CORE.
JRST corer ;NO MORE ROOM...
hrrm t2,chncor ; save it for release.
subi t2,1 ; iowd address begins one down
hrrm t2,bp1 ; save iowd address
addi t2,size ; address for second buffer
hrrm t2,bp2 ; save its iowd address
> ; end ifn ftfsub above
list
MOVE T2,BP1 ;SET UP INITIAL IOWD
MOVEM T2,IBP1
ifoff ftfsub,<
TLNE F,.FHEAD ;IF FILE HAS HEADER,
JRST RETRY1 ;GO ON TO LOCKING STUFF.
ADD T2,[HEDLEN,,HEDLEN]
MOVEM T2,IBP1 ;FUDGE INITIAL IOWD
MOVSI T1,HEADER
HRR T1,BP1 ;SET UP BLT POINTER
ADDI T1,1 ;FUDGE FOR IOWDS
ADDI T2,1
BLT T1,(T2) ;MOVE NON-HEADER INTO BUFFER.
> ;end ife ftfsub above
list
; FALL THROUGH TO LOCKING AND PI SETUP.
SUBTTL LOCKING AND PI SETUP
; FALL THROUGH FROM ABOVE
RETRY1: MOVE SETUP,[EXP LK.HNP!LK.HLS!LK.LNP!LK.LLS] ;LOCK IN CORE
LOCK SETUP,
JRST LOCKER ;LOSING...
LOCKED: HRRZ SETUP,SETUP ;GET RELOCATION FROM LOCK UUO
LSH SETUP,9 ;AND CONVERT PAGE TO WORD ADDRESS
MOVEM SETUP,INDEX ;STORE IN INDEX
MOVEI T1,INDEX ;RELOCATE SOME INSTRUCTIONS
ADDI T1,(SETUP)
HRRM T1,EXCHWD
MOVEI T1,INTRPT
ADDI T1,(SETUP)
HRRM T1,JENWD
MOVE T1,BP1 ;GET BF1 IOWD.
MOVEM T1,diowd ;CREATE IOWD FOR BLKO (RTTRP WILL
;RELOCATE THE ADDRESS IN diowd)
ADDI T1,(SETUP) ;RELOCATE IT
MOVEM T1,RBP1
MOVE T1,BP2 ;GET IOWD FOR BUFFER 2.
ADDI T1,(SETUP)
MOVEM T1,RBP2 ;SAVE IT.
ifon ftfsub,<
pushj p,pshint ; save interrupt system status
> ; end ifn ftfsub above
list
SETOM CCINT ;SET KLUDGE FLAG
MOVEI SETUP,INTBLK ;GRAB ↑C
MOVEM SETUP,.JBINT
ifon FTKSYS,<
SETZM KILFLG ;JUST TO BE SURE
TLNE F,.KSYS ;USER WANTS TIME-SHARING STOPPED?
JRST KSYS ;YUP. DO IT.
> ; END IFN FTKSYS ABOVE
list
MOVEI SETUP,RTBLK ;CONNECT DAC.
RTTRP SETUP,
JRST TRPERR ;AFTER ALL THAT TROUBLE...
MOVSI SETUP,(JRSTF @0);SET UP RTTRP EXIT
ifon FTKSYS,<
JRST PISET
KSYS: MOVE SETUP,[XWD 42,BLKOW]
TRPSET SETUP, ;SET UP PI-CHANNEL 1.
JRST TRPERR
MOVEM SETUP,PIWRD1 ;SAVE OLD CONTENTS FOR RESTORE.
MOVE SETUP,[XWD 43,TRPADR]
TRPSET SETUP, ;
JRST TRPERR
MOVEM SETUP,PIWRD2
SETOM KILFLG
MOVSI SETUP,(JEN @0) ;SET UP TRPSET EXIT
> ; END IFN FTKSYS ABOVE
list
; FALL THROUGH TO BUFFER INITIALISATION
SUBTTL BUFFER INITIALISATION
; FALL THROUGH FROM ABOVE
PISET: HLLM SETUP,JENWD ;SET UP KIND OF INTERRUPT EXIT
SETZM MFLG ;LOWER MISSED FLAG
SETZM DFLG ;LOWER DONE FLAG
MOVE T1,RBP2 ;GET RELOCATED IOWD FOR BUFFER 2.
MOVEM T1,TPOINT ;SET UP NEXT IOWD FOR DAC.
SETOM WHATBF ;POINT WHATBF TO BUFFER 1
SKIPE T1,RUNHPQ ;GET OUR MAXIMUM HPQ.
HPQ T1,
JFCL ;IGNORE.
ifon FTMT,<
TLNE F,.MTDEV ;DO WE HAVE A DISK?
JRST DONEQ
> ; END IFN FTMT ABOVE
list
MOVE T1,[XWD .DUPRI,DSKHPQ]
SKIPE DSKHPQ ;NON-ZERO MAX PRIORITY?
DISK. T1,
JFCL
DONEQ: IN DSK,IBP1 ;FILL FIRST BUFFER FROM DSK
SKIPA
JRST [PUSHJ P,ERREOF; check for eof or error
JRST SETLST ; eof. SET UP LAST IOWD.
JRST BUF2] ; error. ignore and continue.
BUF2: IN DSK,BP2 ;FILL BUFFER 2.
JRST STRDAC
JRST [PUSHJ P,ERREOF; check for error or eof.
JRST EOF2 ; eof. set up last iowd.
JRST STRDAC] ; error. ignore and continue
EOF2: MOVSI T1,-SIZE ;GET SIZE OF A FULL BUFFER
ADDM T1,LIOWD ;UPDATE LAST IOWD.
SETLST: PUSHJ P,GLSTLN ;GET LENGTH OF LAST TRANSFER.
JUMPGE T1,NULFIL ;COMPLAIN ABOUT NULL FILES
HLLM T1,diowd
SETZM LIOWD
SETZM TPOINT ;ZERO NEXT IOWD FOR DAC
STRDAC: DACON ; TURN ON THE DAC
OUTSTR [ASCIZ/
playing
/]
ifon FTMT,<
TRZ F,.ATEOF ;CLEAR "AT EOF" FLAG.
> ; END IFN FTMT
list
STATZ DSK,IO.EOF ;END OF FILE ALREADY?
JRST EOFI ;YUP. FORGET ABOUT MAIN LOOP.
SUBTTL MAIN PLAY LOOP
LOOP:
xlist
IFN 0,< ;DOESN'T WORK ON LOSING SYSTEMS.
SKIPLE T1,SLPTIM ;WAKE WHEN ITS TIME TO START REFILL.
HIBER T1,
JFCL ;HAVE TO STAY AWAKE.
> ;END IFN 0,
list
MOVE P2,WHATBF ;GET BUFFER POINTER FLIP-FLOP
HRRZ P1,RBP1+1(P2) ;GET RELOCATED BUFFER ADDRESS
ADD P1,TIOWD ;GET TIMING IOWD.
TIMCHK: PUSHJ P,ERCHK ;EVERYTHING STILL OK ?
SKIPE TPOINT ;UNLIKELY...BUT...
CAME P2,WHATBF ;YAWN...SHOULD WE PANIC ?
JRST DOREAD ;YIPES! DAC SNUCK BY!
CAML P1,diowd ;HAS DAC REACHED REFILL POINT YET?
JRST TIMCHK ;NOPE. GUESS WE WOKE TO SOON.
;HERE WHEN WE CAN DO THE NEXT READ.
;NOTE. WE MAY HAVE MISSED THE DAC AND IT MAY BE WORKING
;IN THE NEXT BUFFER BUT THATS ALL RIGHT BECAUSE WE ARE USING
;THE OLD "WHATBF" FLAG.
DOREAD: MOVE P1,RBP1+1(P2) ;GET NEXT BUFFER ADDRESS.(RELOCATED)
HRRM P1,LIOWD ;REMEMBER THE ADDRESS IN CASE OF EOF.
IN DSK,BP1+1(P2) ;READ THE BUFFER.
DACWT: SKIPA T2,TPOINT ;HAS DAC STARTED ON NEXT BUFFER?
JRST [PUSHJ P,ERREOF; check for error or eof.
JRST EOF ; eof. wait for dac
JRST RDERR] ; error. ignore and continue.
RDERR: PUSHJ P,ERCHK ; SEE IF THE DAC HAS STOPPED
JUMPN T2,DACWT ; IN CASE WE HAD A DISK ERROR AND
; RETURNED EARLY.
MOVEM P1,TPOINT ;SET UP NEXT IOWD FOR DAC.
JRST LOOP ;AND CONTINUE.
; here on input error or eof.
; returns call + 1 on eof, call + 2 on error.
ERREOF: STATZ DSK,IO.EOF ; check eof bit.
POPJ P, ; eof. return to call + 1.
PUSH P,T1 ; save t1.
OUTSTR [ASCIZ/
? Input error. Device status = /]
GETSTS DSK,T1 ; get device status
PUSHJ P,OCTSP ; type it out in octal
OUTSTR [ASCIZ/. Continuing.../]
XCT SSTINS ; EXECUTE THE SETSTS INSTRUCTION
POP P,T1
AOS (P) ; take skip return
POPJ P,
subttl end of file. cleanup
;HERE TO TERMINATE A RUN,WAIT FOR THE DAC TO FINISH
EOF: PUSHJ P,GLSTLN ;GET LENGTH OF LAST TRANSFER.
JUMPGE T1,EOFI ;NOTHING.
SKIPE TPOINT ;WAIT FOR DAC PLEASE.
JRST .-1
MOVEM T1,TPOINT ;SET UP IOWD FOR LAST READ
EOFI:
ifon FTMT,<
TRO F,.ATEOF ;SET "AT EOF" FLAG.
> ; END IFN FTMT ABOVE
list
X1: SKIPL DFLG ;WAIT FOR DAC TO FINISH.
JRST .-1
ifon FTKSYS,<
TLNE F,.KSYS ;SHOULD WE RESTORE THE SYSTEM.
JRST RSTSYS ;YUP. DO IT.
> ; END IFN FTKSYS ABOVE
list
MOVEI SETUP,RTBOFF
RTTRP SETUP,
JFCL
JRST SYSSET
ifon FTKSYS,<
RSTSYS: SETZ SETUP,
TRPSET SETUP, ;TURN TIME-SHARING BACK ON.
JFCL
SETZM KILFLG ;TURN OFF "DEAD" FLAG.
> ; END IFN FTKSYS ABOVE
list
SYSSET: SETZM .JBINT ;DISABLE ↑C TRAPPING
move setup,[xwd 1,1] ;UNLOCK
UNLOK. SETUP,
JFCL ;IGNORE ANY ERRORS
SETZ T1,
HPQ T1,
JFCL
CLOSE DSK,
ifoff ftfsub,<
HRRZ SETUP,OLDSIZ ; GET OUR OLD SIZE
CORE SETUP, ;REDUCE.
JFCL
> ; end ife ftfsub above
ifon ftfsub,<
hrrz t2,chncor ; get location of extra core
pushj p,correl ; release the core
givchn: hlrz t2,chncor ; get the i/o channel
pushj p,chnrel ; release the channel
pushj p,popint ; restore interrupt system status
> ; end ifn ftfsub
ifon FTMT,<
TLNE F,.MTDEV ;IS IT MAG-TAPE?
TRNN F,.ATOBS ;DO YOU WANT AUTO BACKSPACE?
JRST RETRY2 ;NOPE.
MOVNI T1,1
PUSHJ P,BAKWRD ;COLLECT THOSE FREE BACKSPACES.
> ; END IFN FTMT ABOVE
list
JRST RETRY2 ;GO BACK FOR MORE
;HERE TO CHECK THE DAC FOR VARIOUS ERRORS
ERCHK: SKIPE MFLG ;THIS CAN ONLY HAPPEN IF SOMEONE HAS
JRST MISSED ;TURNED OFF THE PI SYSTEM FOR TOO LONG
SKIPE DFLG ;IF DONE FLAG IS RAISED HERE - ERROR
JRST SLOW ;NEXT IOWD WAS NOT READY
DACIO (CONSO,BUSY) ;IS DAC ALIVE?
JRST DEADAC ;NOPE. DON'T BOTHER WAITING
POPJ P,
subttl user errors
; here on syntax error trying to parse command string
SYNERR: JFCL
erioin:
ifon ftfsub,<
; here on any initialisation i/o error if we have been called from FORTRAN.
; give the i/o channel back to FOROTS.
hlrz t2,chncor ; get FOROTS allocated i/o channel.
pushj p,chnrel ; release the channel.
> ; end ifn ftfsub above
list
ERRET: OUTSTR CRLF
jrst retry2 ; go back to command loop or return if sub
; here when we can't open input device
INITER: OUTSTR [ASCIZ /?Can't open input device /]
MOVE T1,DEV ;GET DEVICE NAME.
PUSHJ P,TYDEV ;TYPE IT OUT.
jrst erioin ;TAKE COMMON ERROR RETURN
; here when we can't lookup input file.
LKUPER: OUTSTR [ASCIZ /?Can't find /]
MOVE T1,DEV
MOVE T2,FILE
MOVE T3,EXT
MOVE T4,MUSPPN
PUSHJ P,TYSPEC ;TYPE FILE SPEC
OUTSTR [ASCIZ /
LOOKUP error code = /]
HRRZ T1,FILEXT ;GET ERROR CODE
PUSHJ P,OCTOUT ;AND TYPE IT
jrst erioin
; here in i/o error trying to read in header.
HEDERR: OUTSTR [ASCIZ\
?I/O error trying to read header block\]
jrst erioin
; here on zero length file.
NULFIL: OUTSTR [ASCIZ/
?Zero length file !/] ;EVEN PARANOID PEOPLE HAVE ENEMIES
jrst erioin ;AND TRY AGAIN.
subttl real time initialisation errors
; here when we can't get enough core.
CORER: OUTSTR [ASCIZ /?Can't get core/]
jrst erioin ; give back i/o channel and try again.
; here when we can't lock.
LOCKER: OUTSTR [ASCIZ /?Can't lock.
LOCK error code = /]
MOVE T1,SETUP ;GET ERROR CODE ***** WHY NOT OMIT???
PUSHJ P,OCTOUT
;;;;; exit 1, ; back to monitor on this one
JRST SYSSET ; GO BACK TO 1ST PROMPT
ifn 0,< OUTSTR [ASCIZ/
Sleeping. Will try again a little later.
/]
RELOCK: SKPINC ;IF USER TYPES, EXIT
SKIPA
jrst [outstr [asciz /
[type CONTinue to keep trying/]
EXIT 1, ;SO CONTINUE WILL.
jrst relok1]
relok1: MOVEI SETUP,6
SLEEP SETUP,
> ; end ifn 0 above
MOVE SETUP,[XWD 1,1];TRY AGAIN
LOCK SETUP,
jrst locker ;KEEP TRYING
OUTSTR [ASCIZ /[LOCKED]
/]
JRST LOCKED
TRPERR: OUTSTR [ASCIZ /?Can't set up PI locations
/]
jrst sysset ; core down and give back i/o channel
subttl dac and playing errors
; here when no next pointer. Dac has raised done flag but there are more
; samples to send.
SLOW: OUTSTR [ASCIZ /
?Could not read input fast enough?
/]
jrst popret ; pop off call and return.
; here when Dac raises data-missed flag. Someone has turned off the
; interrupt system or we spent too much time in a higher priority
; interrupt routine.
MISSED: OUTSTR [ASCIZ /
?Took too long to service interrupt.
/]
popret: POP P,(P) ;GET RID OF CALL
JRST X1
; here when Dac doesn't respond to being turned on,
; or it has turned itself off.
DEADAC: OUTSTR [ASCIZ /
?Dac is dead.
/]
POP P,(P)
JRST PANIC
; here if we hit EOT while reading mag-tape.
ifon FTMT,<
EOTER: OUTSTR [ASCIZ /
?Hit end of tape./]
jrst erioin ; give back i/o channel if we have one.
> ; END IFN FTMT ABOVE
list
subttl <ctrl c> processing and other panic stops
;HERE ON ↑C INTERRUPT
INTLOC: PUSH P,INTBLK+2 ;WHERE ARE WE COMING FROM ?
SETZM INTBLK+2 ;LET ↑C NEST
AOSGE CCINT
POPJ P, ;WE'VE BEEN HERE BEFORE.
SKIPGE DFLG ;IS DAC OFF?
JRST X1 ;YUP. JUST UNLOCK ETC.
;HERE ON A PANIC STOP
PANIC: DACOFF ; TURN OFF THE DAC
SETOM DFLG ;AND SET FLAG FOR OTHERS
ifon FTKSYS,<
SKIPL KILFLG ;DO WE HAVE TO RESTORE THE SYSTEM?
JRST X1
SETZM TPOINT ;MAKE SURE THERE IS NO DATA READY
MOVNI T1,1 ;FAKE THE END OF A BLKO.
HRLM T1,diowd
CONO PI,1B24!1B29 ;FAKE AN INTERRUPT.
> ; END IFN FTKSYS ABOVE
list
JRST X1
SUBTTL SUBROUTINES
;ROUTINE TO GET A CHARACTER INTO T1
INCHAD:
ifoff ftfsub,<
INCHWL T1
CAIN T1,3 ;↑C?
EXIT
> ; end ife ftfsub
ifon ftfsub,<
ildb t1,spcadd ; get byte
> ; end ifn ftfsub above
list
CAIL T1,141 ;CHECK FOR LOWER CASE.
CAILE T1,172
POPJ P,
TRZ T1,40 ;CONVERT TO UPPER CASE.
POPJ P,
SUBTTL CLOCK SUBROUTINES
ifon FT16B,<
; HERE TO SET CLOCK RATE FOR NEW DAC
; ON RETURN, T2 CONAINS CLOCK BITS, T1 CONTAINS SAMPLING RATE
; SKIP RETURN ON EXACT MATCH
NCLK: MOVE T1,[↑D1000000] ; 10 ↑ 6
IDIV T1,@SRATE ; CONVERT TO SAMPLING PERIOD IN MICRO SECS
CAIG T1,1
JRST TF ; TOO HIGH A CLOCK RATE
CAILE T1,400
JRST TS ; TOO LOW A CLOCK RATE
JUMPE T2,COK ; JUST RIGHT
JRST NBDCLK
TF: MOVEI T1,2
JRST NBDCLK
TS: MOVEI T1,377
JRST NBDCLK
COK: AOS (P)
NBDCLK: HRRZI T2,-1(T1) ; GET CLOCK BITS
MOVE T3,[↑D1000000]
IDIVM T3,T1 ; CONVERT BACK TO SAMPLING RATE
POPJ P,
> ; END IFN FT16B
list
ifon FT12B,<
; HERE TO SET CLOCK RATE FOR OLD DAC
; RETURN T2 CONTAINS CLOCK BITS, T1 CONAINS SAMPLING RATE
; SKIP RETURN ON EXACT MATCH
OCLK: MOVSI T3,-NMCLK ;SET UP AOBJN POINTER.
CLKCHK: HRRZ T1,CLKTAB(T3) ;GET A VALID CLOCK RATE.
CAMN T1,@SRATE ;MATCH?
JRST GOTCLK ;YUP.
CAML T1,@SRATE ;IS THIS THE "BEST".
JRST DEFCLK ;USE IT FOR NOW.
AOBJN T3,CLKCHK ;TRY NEXT ENTRY
SOJA T3,DEFCLK ;POINT T3 TO LAST ENTRY
GOTCLK: AOS (P) ;GIVE GOOD RETURN
DEFCLK: HLRZ T2,CLKTAB(T3) ;GET CLOCK BITS.
POPJ P, ;RETURN
DEFINE CLKRAT <
DEFINE X(CBITS,FREQ)
< XWD CBITS,↑D<FREQ> >
X (2,4000)
X (12,5000)
X (3,6400)
X (4,8000)
X (14,10000)
X (5,12800)
X (6,16000)
X (16,20000)
X (25,25600)
X (7,32000)
X (17,40000)
X (27,64000)
X (37,80000)
>
CLKTAB: CLKRAT
NMCLK=.-CLKTAB
> ; END IFN FT12B
list
SUBTTL DAC SPECIFIC SUBROUTINES
ifon FTMDAC,<
;HERE TO START THE DAC.
ODACON: HRRZ T1,CONOWD ; GET THE CONOWD
TRO T1,DONE!ON!DACPI; TURN ON GOOD BITS
HRRM T1,CONOWD ; RESET THE CONOWD
XCT CONOWD ; DO THE CONO.
POPJ P,
; HERE TO STOP THE OLD DAC
ODACOF: DACIO (CONO,OFF) ; CONO OFF THE DAC
POPJ P,
; HERE TO START THE NEW DAC
NDACON: HRRZ T1,CONOWD ; GET THE CONO
TRO T1,DONE!ON!DACPI; TURN ON GOOD BITS
HRRM T1,CONOWD
XCT CONOWD
POPJ P,
; HERE TO STOP THE NEW DAC
NDACOF: DACIO (CONO,OFF) ; TURN THE DAC OFF
DACIO (CONI,DACSTT) ; AND READ IN THE STATUS
POPJ P,
> ; END IFN FTMDAC
list
;HERE TO COMPUTE THE LENGTH OF THE LAST TRANSFER
GLSTLN: MOVE T1,LIOWD
ifon FTMT,<
TLNN F,.MTDEV ;IS IT MAG-TAPE?
JRST GOTLST ;NOPE. DONE.
MOVEI T1,DSK ;YUP. HAVE TO DO MORE WORK.
MTCHR. T1, ;GET SOME DATA
POPJ P, ;DIDN'T WORK.
HLLZS T1 ;GET WORD COUNT.
MOVNS T1 ;NEGATE IT.
HRR T1,LIOWD ;STICK IN THE LAST BUFFER ADDRESS.
> ; END IFN FTMT ABOVE
list
GOTLST: TLZ T1,3 ;MAKE IT MULTIPLE OF 4 WORDS.
POPJ P, ;DONE.
ifon FTMT,<
;HERE TO BACKSPACE TAPE
BAKWRD: TROE F,.ATEOF ;SET THE "AT EOF" FLAG.
BAK1: MTBSF. DSK, ;BACKSPACE 1 FILE,
MTWAT. DSK, ;WAIT FOR IT.
STATZ DSK,IO.BOT ;BOT?
POPJ P, ;YUP. GUESS WE CAN STOP NOW.
AOJLE T1,BAK1 ;NOPE CONTINUE.
MTSKF. DSK, ;SKIP OVER LAST EOF MARK
POPJ P, ;RETURN
> ; END IFN FTMT ABOVE
list
DODAC ; GENERATE THE TABLE OF POINTERS TO I/O INST.
ifoff ftfsub,<
END
> ; end ife ftfsub above
ifon ftfsub,<
end
> ; end ifn ftfsub above
list